package com.wind.plugin.annotator;

import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.XmlRecursiveElementVisitor;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlTag;
import com.intellij.psi.xml.XmlText;
import org.jetbrains.annotations.NotNull;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.wind.plugin.common.Common.getCurPattern;
import static com.wind.plugin.window.Utils.annotateRange;

/**
 * @author wind
 * @version 1.0
 * @description: TODO
 * @date 2025/2/18 15:12
 */
public class XmlCurAnnotator implements Annotator {
    // 优化正则表达式（支持更多边界情况）
    private static final Pattern CUR_PATTERN = Pattern.compile(
            "(?i)\\b(CUR(_CODE)?|curr|NBCB_CUR_CODE|CURRENCY_ID)\\b|\\$\\{cur\\w+\\}"
    );
    @Override
    public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
        if (element instanceof PsiFile) {
            element.accept(new MapperXmlVisitor(holder));
        }

    }
}

class MapperXmlVisitor extends XmlRecursiveElementVisitor {
        private final AnnotationHolder holder;
        private final Set<TextRange> processedRanges = new HashSet<>();

        public MapperXmlVisitor(AnnotationHolder holder) {
            this.holder = holder;
        }

        @Override
        public void visitXmlText(XmlText text) {
            // 精准处理 SQL 文本内容
            if (isInDmlContext(text)) {
                processTextContent(text);
            }
            super.visitXmlText(text);
        }

        private void processTextContent(XmlText xmlText) {
            String fullText = xmlText.getText();
            Matcher matcher = getCurPattern().matcher(fullText);

            // 按文本块处理（修复多行文本偏移量问题）
            TextRange parentRange = xmlText.getTextRange();
            while (matcher.find()) {
                TextRange matchRange = new TextRange(
                        parentRange.getStartOffset() + matcher.start(),
                        parentRange.getStartOffset() + matcher.end()
                );

                if (!processedRanges.contains(matchRange)) {
                    processedRanges.add(matchRange);
                    annotateRange(matchRange.getStartOffset(), matchRange.getEndOffset(),
                            holder, "币种项需注意");
                }
            }
        }

        private boolean isInDmlContext(XmlText text) {
            XmlTag xmlTag = PsiTreeUtil.getParentOfType(text, XmlTag.class);
            if (xmlTag !=null && isDmlTag(xmlTag)){
                return true;
            }
            return false;
        }

    private boolean isDmlTag(XmlTag tag) {
        return new HashSet<>(Arrays.asList("insert", "update", "delete", "select", "sql", "resultmap", "if", "foreach"))
                .contains(tag.getName().toLowerCase());
    }
}
